package cn.taobaoke.restful.controller;

import cn.taobaoke.restful.domain.AgentEntity;
import cn.taobaoke.restful.domain.PIDEntity;
import cn.taobaoke.restful.exception.TBKException;
import cn.taobaoke.restful.service.AgentService;
import cn.taobaoke.restful.service.GlobalConfigService;
import cn.taobaoke.restful.service.PIDService;
import cn.taobaoke.restful.service.TaobaoApi;
import cn.taobaoke.restful.util.GsonUtil;
import cn.taobaoke.restful.util.OkHttpUtil;
import cn.taobaoke.restful.util.StringUtil;
import lombok.NonNull;
import lombok.RequiredArgsConstructor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.io.IOException;
import java.util.*;

/**
 * WxSenderController类.
 * +-----------------------------------------------------------------------------------------------+
 * |类名称: WxSenderController                                                                         |
 * |创建时间: 7/2/17                                                                               |
 * |功能简介:                                                                                       |
 * |参考链接:                                                                                       |
 * +-----------------------------------------------------------------------------------------------+
 *
 * @author luch
 */
@RestController
@RequestMapping("/{domain}/{domainId}/api")
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
public class WxSenderController extends BaseController {

    private static Logger logger = LoggerFactory.getLogger(WxSenderController.class);

    //    private static String WX_SENDER_CENTER_HOST = "http://172.18.142.173:3012";
    private static String WX_SENDER_CENTER_HOST = "http://localhost:3012";
    private static String DEFAULT_COUPON_URL = "http://yhq.gittis.co";
    private static String C015_CENTER_HOST = "http://wx.pp028.cn";
    private static String C015_COUPON_URL = "http://coupon.pp028.cn";
    private static String C006_CENTER_HOST = "http://120.92.162.251:3012";

    private final
    @NonNull
    AgentService agentService;

    private final
    @NonNull
    PIDService pidService;


    private final
    @NonNull
    TaobaoApi taobaoApi;

    private final
    @NonNull
    GlobalConfigService globalConfigService;

    private String getSendProductTemplate(final Long domainId) {
        Map<String, Object> globalConfig = globalConfigService.queryConfig(domainId);
        return (String) globalConfig.get("template");
    }

    private static String getHost(String domain) {
        if ("c015".equals(domain)) {
            // C015 客户放在他们自己电脑上的
            return C015_CENTER_HOST;
        }
//        if ("c006".equals(domain) || "c028".equals(domain)) {
//            return C006_CENTER_HOST;
//        }

        return WX_SENDER_CENTER_HOST;
    }

    private static String getCouponUrl(String domain) {
        if ("c015".equals(domain)) {
            return C015_COUPON_URL;
        }
        return DEFAULT_COUPON_URL;
    }

    @GetMapping("/wxsender")
    public Result getWxSenderForAdmin(@PathVariable String domain, @PathVariable Long domainId) throws IOException {
        String url = String.format("%s/api/%s/container", getHost(domain), domain);
        String ret = OkHttpUtil.DEFAULT.get(url);

        Map<String, Object> map = GsonUtil.getObject(ret);
        if (map == null || !map.containsKey("data")) {
            throw new TBKException("获取扫码机器人信息失败 => " + ret);
        }

        Boolean success = (Boolean) map.get("success");
        if (!success) {
            throw new TBKException("获取扫码机器人信息失败 => " + ret);
        }

        if (map == null || !map.containsKey("data")) {
            return wrapObj(Collections.EMPTY_LIST);
        }

        List<Map> mapList = (List<Map>) map.get("data");
        if (mapList == null || mapList.isEmpty()) {
            return wrapObj(Collections.EMPTY_LIST);
        }

        Map<Long, Map> idToMap = new HashMap<>();
        List<Long> agentIds = new ArrayList<>(mapList.size());
        for (Map containerMap : mapList) {
            containerMap.remove("config");
            Long agentId = Long.valueOf((String) containerMap.get("tk_agent"));
            agentIds.add(agentId);
            idToMap.put(agentId, containerMap);
        }
        logger.info("agentIds => {}", agentIds);
        if (agentIds.size() > 0) {
            List<AgentEntity> agents = agentService.getAgentByIdIn(agentIds, domainId);
            logger.info("find agentIds => {}", agents.size());
            for (AgentEntity agent : agents) {
                Long agentId = agent.getId();
                Map containerMap = idToMap.get(agentId);
                containerMap.put("agent", agentService.filterPassword(agent));
            }
        }
        return wrapObj(mapList);
    }

    @PostMapping("/wxsender/upgrade")
    public String upgradeWxsender(@PathVariable String domain) throws IOException {
        String upgradeAPI = String.format("%s/api/container/upgrade", getHost(domain));
        return OkHttpUtil.DEFAULT.postJson(upgradeAPI, "");
    }


    /**
     * 获取微信发单机器人信息
     *
     * @param domain
     * @param agentId
     * @return
     * @throws IOException
     */
    @GetMapping("/agent/{agentId}/wxsender")
    public Result getWxSenderConfig(@PathVariable String domain, @PathVariable Long agentId) throws IOException {
        String url = String.format("%s/api/container/info?identity=%s", getHost(domain), genIdentity(domain, agentId));
        String jsonRet = OkHttpUtil.DEFAULT.get(url);
        Object ret = parseRet(jsonRet);
        Map<String, Object> map = (Map<String, Object>) ret;
        map = setDefaultWsSenderInfo(domain, agentId, map);
        return wrapObj(map);
    }


    @GetMapping("/wxsender/pid")
    public Result getSenderPidByIdentity(@PathVariable String domain, @PathVariable Long domainId, String identity) {
        if (identity == null) throw new TBKException("identit 不能为空");

        String items[] = identity.split("_");
        //        wx_c008_1_default
        if (items.length != 4) {
            throw new TBKException("非法格式的identity");
        }
        String agentIdStr = items[2];
        if (StringUtil.isNumeric(agentIdStr)) {
            Long agentId = Long.valueOf(agentIdStr);
            AgentEntity agentEntity = agentService.getAgentById(agentId, domainId);
            if (agentEntity == null) {
                throw new TBKException("identity 有误, 不存在对应的代理");
            }
            return wrapObj(agentEntity.getPid());
        } else {
            // admin
            PIDEntity pidEntity = pidService.getOrCreateAdminPid(domainId);
            return wrapObj(pidEntity.getPid());
        }
    }


    @PostMapping("/wxsender/tkl")
    public Result getWxSenderTkl(@PathVariable String domain, @PathVariable Long domainId, @RequestBody Map<String, Object> map) {
        if (map == null || !map.containsKey("identity") || !map.containsKey("couponUrl")) {
            throw new TBKException("identity, couponUrl cann't be empty");
        }

        String identity = (String) map.get("identity");
        String couponUrl = (String) map.get("couponUrl");

        String pid = getPidFromIdentity(identity, domainId);
        String tkl = taobaoApi.getTaokoulinByCouponAndPid(domain, couponUrl, pid);
        return wrapObj(tkl);
    }

    private String getPidFromIdentity(String identity, final Long domainId) {
        String items[] = identity.split("_");
        //        wx_c008_1_default
        if (items.length != 4) {
            throw new TBKException("非法格式的identity");
        }
        String agentIdStr = items[2];
        if (StringUtil.isNumeric(agentIdStr)) {
            Long agentId = Long.valueOf(agentIdStr);
            AgentEntity agentEntity = agentService.getAgentById(agentId, domainId);
            if (agentEntity == null) {
                throw new TBKException("identity 有误, 不存在对应的代理");
            }
            return agentEntity.getPid();
        } else {
            // admin
            PIDEntity pidEntity = pidService.getOrCreateAdminPid(domainId);
            return pidEntity.getPid();
        }
    }


    @PostMapping("/agent/{agentId}/wxsender/start")
    public Result startWxSender(@PathVariable String domain, @PathVariable Long domainId, @PathVariable Long agentId, @RequestBody Map config) throws IOException {
        if (config == null) {
            throw new TBKException("配置信息不能为空");
        }
        String groupKeyword = (String) config.get("group_keyword");
        if (groupKeyword == null || groupKeyword.trim().isEmpty()) {
            throw new TBKException("微信群 不能为空");
        }

        Map<String, Object> map = new HashMap<>();
        map.put("config", config);
        map = setDefaultWsSenderInfo(domain, agentId, map);

        String template = getSendProductTemplate(domainId);
        if (template != null) {
            config.put("template", template);
        }

//        if (!"test".equals(domain)) {
//            throw new TBKException("等待技术修复, 预计周一上线");
//        }

        if (!"c011".equals(domain) && !"c008".equals(domain) && !"c026".equals(domain) && !"c027".equals(domain) && !"c015".equals(domain) && !"c000".equals(domain) && !"test".equals(domain) && !"c006".equals(domain) && !"c028".equals(domain)) {
            throw new TBKException("没有更多电脑资源,请联系管理员");
        }

        String url = String.format("%s/api/container/create", getHost(domain));
        String jsonRet = OkHttpUtil.DEFAULT.postJson(url, GsonUtil.getJsonString(map));
        Object ret = parseRet(jsonRet);
        return wrapObj(ret);
    }

    @PostMapping("/agent/{agentId}/wxsender/stop")
    public Result stopWxSender(@PathVariable String domain, @PathVariable Long agentId) throws IOException {
        String url = String.format("%s/api/container/stop?identity=%s", getHost(domain), genIdentity(domain, agentId));

        String jsonRet = OkHttpUtil.DEFAULT.postJson(url, "");

        Object ret = parseRet(jsonRet);
        return wrapObj(ret);
    }

    @PostMapping("/agent/{agentId}/wxsender/logout")
    public Result closeWxSender(@PathVariable String domain, @PathVariable Long agentId) throws IOException {
        String url = String.format("%s/api/container/close?identity=%s", getHost(domain), genIdentity(domain, agentId));

        String jsonRet = OkHttpUtil.DEFAULT.postJson(url, "");

        Object ret = parseRet(jsonRet);
        return wrapObj(ret);
    }

    @PostMapping("/agent/{agentId}/wxsender/restart")
    public Result restartWxSender(@PathVariable String domain, @PathVariable Long domainId, @PathVariable Long agentId, @RequestBody Map config) throws IOException {
        String url = String.format("%s/api/container/restart?identity=%s", getHost(domain), genIdentity(domain, agentId));
        config = mergeWithDefaultConfig(domain, config);

        String template = getSendProductTemplate(domainId);
        if (template != null) {
            config.put("template", template);
        }

        String jsonRet = OkHttpUtil.DEFAULT.postJson(url, GsonUtil.getJsonString(config));
        Object ret = parseRet(jsonRet);
        return wrapObj(ret);
    }


    private static Map<String, Object> setDefaultWsSenderInfo(String domain, Long agentId, Map<String, Object> map) {
        if (map == null) map = new HashMap<>();

        if (!map.containsKey("tk_domain")) {
            map.put("tk_domain", domain);
        }
        if (!map.containsKey("tk_agent")) {
            map.put("tk_agent", agentId.toString());
        }
        if (!map.containsKey("identity")) {
            map.put("identity", genIdentity(domain, agentId));
        }
        if (!map.containsKey("startid")) {
            map.put("startid", 1);
        }

        if (!map.containsKey("status")) {
            map.put("status", "close");
        }

        Map<String, Object> config = (Map<String, Object>) map.get("config");
        config = mergeWithDefaultConfig(domain, config);
        map.put("config", config);
        return map;
    }


    private static Map<String, Object> mergeWithDefaultConfig(String domain, Map config) {
        if (config == null) config = new HashMap();

        config.put("server_host", String.format("http://%s.gittis.co:8080", domain));

//        if (!config.containsKey("group_keyword")) {
//            config.put("group_keyword", "test002");
//        }

        if (!config.containsKey("friend_welcome")) {
            config.put("friend_welcome", "Hi, 欢迎新朋友进入淘宝天猫优惠券群");
        }
        if (!config.containsKey("coupon_url")) {
            config.put("coupon_url", getCouponUrl(domain));
        }
        if (!config.containsKey("send_internal")) {
            config.put("send_internal", 60 * 5);
        }


        if (!config.containsKey("answers")) {
            HashMap answers = new HashMap();
            answers.put("什么群", "淘宝天猫内部优惠券群");
            answers.put("怎么用", "搜索 + 商品关键字 寻找需要的商品");
            config.put("answers", answers);
        }

        if (!config.containsKey("morning_start_hour")) {
            config.put("morning_start_hour", 8);
        }
        if (!config.containsKey("morning_start_minute")) {
            config.put("morning_start_minute", 0);
        }
//        if (!config.containsKey("morning_end_hour")) {
        config.put("morning_end_hour", 12);
//        }
//        if (!config.containsKey("morning_end_minute")) {
        config.put("morning_end_minute", 0);
//        }

//        if (!config.containsKey("afternoon_start_hour")) {
        config.put("afternoon_start_hour", 12);
//        }
//        if (!config.containsKey("afternoon_start_minute")) {
        config.put("afternoon_start_minute", 1);
//        }
//        if (!config.containsKey("afternoon_end_hour")) {
        config.put("afternoon_end_hour", 18);
//        }
//        if (!config.containsKey("afternoon_end_minute")) {
        config.put("afternoon_end_minute", 0);
//        }

//        if (!config.containsKey("night_start_hour")) {
        config.put("night_start_hour", 18);
//        }
//        if (!config.containsKey("night_start_minute")) {
        config.put("night_start_minute", 1);
//        }
        if (!config.containsKey("night_end_hour")) {
            config.put("night_end_hour", 23);
        }
        if (!config.containsKey("night_end_minute")) {
            config.put("night_end_minute", 0);
        }

        return config;
    }


    private static String genIdentity(String adminDomain, Long agentId) {
        return String.format("wx_%s_%d_default", adminDomain, agentId);
    }

    private static Object parseRet(String json) {
        logger.debug("response => {}", json);

        Map<String, Object> map = GsonUtil.getObject(json);

        Boolean success = (Boolean) map.get("success");
        if (success != null && success) {
            return map.get("data");
        } else {
            Object obj = map.get("msg");
            logger.error("parse wxsender failed => {}", GsonUtil.getJsonString(obj));
            if (obj instanceof String) {
                throw new TBKException(obj.toString());
            } else {
                throw new TBKException(GsonUtil.getJsonString(obj));
            }

        }
    }

}
